package com.kitty.game.fight.bean;

import com.kitty.game.pet.model.Pet;
import com.kitty.game.pet.model.PetBook;
import com.kitty.game.role.model.Role;
import com.kitty.game.skill.model.RoleSkill;
import com.kitty.common.utils.SpringUtils;   //1
import com.kitty.game.enter.FiedValue;   //2
import com.kitty.game.fight.book.BookSkillProcessor;
import com.kitty.game.fight.message.vo.FightMember;
import com.kitty.game.fight.service.CountService;
import com.kitty.game.fight.util.FightRateUtil;
import com.kitty.mina.cache.SessionUtils;
import lombok.Getter;
import org.apache.mina.core.session.IoSession;
import org.nutz.lang.util.NutMap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PetFightObject extends FightObject {

    private static final NutMap publicAutoSet = NutMap.NEW();

    private FightObject master;

    @Getter
    private Pet pet;

    /**
     * 天书防御技能 round -> bookName
     */
    private Map<Integer, String> defenseBooks = new HashMap<>();

    /**
     * 天书攻击技能 round -> bookName
     */
    private Map<Integer, String> attackBooks = new HashMap<>();

    private Map<Byte, List<PetBook>> petBooks = new HashMap<>();

    /**
     * 忠诚度
     */
    private int loyal = 100;

    static {
        publicAutoSet.setv("type", 1);
        publicAutoSet.setv("action", 1);
        publicAutoSet.setv("list", new ArrayList<>());
    }

    public PetFightObject(Pet pet, FightObject master, int pos) {
        this.master = master;
        Map<String, Object> autoSet = pet.getAutoFightSet();
        if (autoSet == null) {
            autoSet = publicAutoSet;
        }
        setName(pet.getName());
        setFightMsg(pet.getShouts());
        setLevel(pet.getLevel());
        setId(pet.getId());
        CountService countService = SpringUtils.getHurtService();

        setSpecial_icon(pet.getSpecial_icon());
        if(pet.getSpecial_icon() == 0){
            setSpecialiconIsok(0);
        }else {
            setSpecialiconIsok(1);
        }

        setDefense(countService.countPetMaxDefense(pet));
        setSpeed( countService.countPetMaxSpeed(pet));
        setMagPower(countService.countPetMaxMagPower(pet));
        setPhyPower(countService.countPetMaxPhyPower(pet));
        setMaxLife(countService.countPetMaxLife(pet));
        setMaxMana(countService.countPetMaxMana(pet));
        setCurrMana(pet.getCurrMana());
        setCurrLife(pet.getCurrLife());
        setIcon(pet.getIcon());
        setPolar(pet.getPolar());
        this.pet = pet;
        setASide(master.isASide);
        setPos(pos);
        setHostId(master.getId());
        setTargetId(pet.getId());
        setPos(pos);
        setAutoSkillId((Integer) autoSet.getOrDefault("skillId", 0));
        setSkillId((Integer) autoSet.getOrDefault("skillId", 0));
        setType((Integer) autoSet.getOrDefault("type", 0));
        setMultiIndex(((Integer) autoSet.getOrDefault("multi", 0)).byteValue());
        setAutoFightType((Integer) autoSet.getOrDefault("type", 0));
        setAction(((Integer) autoSet.getOrDefault("action", 0)).byteValue());
//        setSkillGroups(autoSet.getAsList("list", SkillGroup.class));

        Map<Integer, PetBook> allBooks = master.getRole().getPetBox().getPetBooks(pet.getId());
        for (Map.Entry<Integer, PetBook> entry : allBooks.entrySet()) {
            PetBook book = entry.getValue();
            String bookName = book.getBookName();
            if (BookSkillProcessor.mag.contains(bookName)) {
                petBooks.putIfAbsent(BookSkillProcessor.TYPE_MAG, new ArrayList<>());
                petBooks.get(BookSkillProcessor.TYPE_MAG).add(book);
            }
            if (BookSkillProcessor.phy.contains(bookName)) {
                petBooks.putIfAbsent(BookSkillProcessor.TYPE_PHY, new ArrayList<>());
                petBooks.get(BookSkillProcessor.TYPE_PHY).add(book);
            }
            if (BookSkillProcessor.def.contains(bookName)) {
                petBooks.putIfAbsent(BookSkillProcessor.TYPE_DEF, new ArrayList<>());
                petBooks.get(BookSkillProcessor.TYPE_DEF).add(book);
            }
        }
    }

    @Override
    public RoleSkill getSkillBy(int skillId) {
        return pet.getSkillBox().querySkillBy(skillId);
    }

    public List<PetBook> getBooksBy(byte type) {
        return petBooks.getOrDefault(type, new ArrayList<>());
    }

    public int getHostId() {
        return master.getId();
    }

    public Role getRole() {
        return master.getRole();
    }

    @Override
    public long getHostUid() {
        return master.getRole().getId();
    }

    @Override
    public FightMember asFightMember() {
        // 宠物
        FightMember fightMember = new FightMember();
        fightMember.setId(getId());
        fightMember.setWeapon_icon((short) 0);
        fightMember.setColor((short) 2);
        fightMember.setPosition((short) getPos());
        fightMember.setIcon((short) getIcon());
        fightMember.setList(asFieldValues());
        //  宠物时装
        fightMember.setSpecial_icon(getSpecial_icon());
        return fightMember;
    }

    @Override
    public List<FiedValue> asFieldValues() {
        ArrayList<FiedValue> fiedValues = new ArrayList<>();
        fiedValues.add(new FiedValue(1, 4, getName()));
        fiedValues.add(new FiedValue(40, 7, getIcon()));
        fiedValues.add(new FiedValue(41, 7, (short) 32768));
        fiedValues.add(new FiedValue(204, 3, getHostId()));
        fiedValues.add(new FiedValue(341, 1, (byte) 0));
        fiedValues.add(new FiedValue(340, 1, (byte) 0));
        fiedValues.add(new FiedValue(12, 3, getMaxMana()));
        fiedValues.add(new FiedValue(11, 3, getCurrMana()));
        fiedValues.add(new FiedValue(6, 3, getCurrLife()));
        fiedValues.add(new FiedValue(7, 3, getMaxLife()));
        return fiedValues;
    }

    @Override
    public NutMap getExtraAttr() {
        return getPet().getExtraAttr();
    }

    @Override
    public int getMagHurt(FightObject target, boolean isPenetrate) {
        RoleSkill roleSkill = getSkillBy(getSkillId());
        int targetResist = getTargetResistValue(target);// 抗性

        Fight fight = SpringUtils.getFightService().getFightByRoleId(getId());
        // 降魔斩--有一定几率忽视对方的法术抗性
        if (BookSkillProcessor.attackTrigger(fight, this, target, BookSkillProcessor.XIANG_MO)) {
            targetResist = 0;
        }

        double attackPercent = getExtraAttr().getDouble("attack", 0.0);

        Double result = (getExtraAttack() + this.getMagPower() + this.getMagPower() * attackPercent) * 1.05
                + roleSkill.getSkillJieshu() * 10 * this.getLevel() * 1.6
                + FightRateUtil.getRandHurt(this.getMagPower())
                - (targetResist * 50 + target.getDefense() + target.getExtraDefense());
        /** 计算星君的抵抗 */
        //这里修复仙道点的减伤
        result =(double)CountService.getHurtByReduce(result.intValue(),target,true);
        if (target.getXinjun() != null) {
            result = countAbsorb(getHostUid(), result, target.getXinjun().getMag_absorb());
        }
        return result.intValue();
    }

    @Override
    public int getPhyHurt(FightObject target, boolean isPenetrate) {
        double attackPercent = getExtraAttr().getDouble("attack", 0.0);
        Double result = (getExtraAttack() + this.getPhyPower() + this.getPhyPower() * attackPercent) * 1.3
                + FightRateUtil.getRandHurt(this.getPhyPower()) - target.getDefense() - target.getExtraDefense();
        //这里修复仙道点的减伤
        result =(double)CountService.getHurtByReduce(result.intValue(),target,true);
        /** 计算星君的抵抗 */
        if (target.getXinjun() != null) {
            result = countAbsorb(getHostUid(), result, target.getXinjun().getPhy_absorb());
        }
        return result.intValue();
    }

    public void reduceLoyal(int changeVal) {
        if (changeVal > 0) {
            this.loyal -= changeVal;
            this.loyal = Math.max(0, loyal);
        }
    }

    public int getLoyal() {
        return loyal;
    }

    @Override
    public IoSession getSession() {
        return SessionUtils.getSessionBy(this.getHostUid());
    }

    public Map<Integer, String> getDefenseBooks() {
        return defenseBooks;
    }

    public Map<Integer, String> getAttackBooks() {
        return attackBooks;
    }

    @Override
    public String toString() {
        return "PetFightObject{" + "id=" + id + ", name='" + name + '\'' + '}';
    }

}
